home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 1.iso
/
DEMON
/
RISCOS2
/
TCP_131S.ARC
/
c
/
AX25DUMP
< prev
next >
Wrap
Text File
|
1994-03-03
|
12KB
|
318 lines
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "global.h"
#include "mbuf.h"
#include "ax25.h"
#include "timer.h"
#include "lapb.h"
#include "trace.h"
#include "arp.h"
#include "ip.h"
#include "misc.h"
#include "netrom.h"
static void netrom_dump(struct mbuf **);
/* Dump an AX.25 packet header */
void ax25_dump(struct mbuf **bpp, int check)
{
char tmp[20], tmp1[20];
char control,pid,seg,ipcam;
int16 type;
struct ax25 hdr;
struct ax25_addr *hp;
int unsegmented;
char header[128];
char buf[80];
struct mbuf *temp;
check = check;
/* Extract the address header */
if(ntohax25(&hdr,bpp) < 0){
/* Something wrong with the header */
twprintf("AX25: bad header\n");
return;
}
pax25(tmp,&hdr.source);
pax25(tmp1,&hdr.dest);
sprintf(header,"AX25: %s->%s ", tmp, tmp1);
if(hdr.ndigis > 0){
strcat(header,"v ");
for(hp = &hdr.digis[0]; hp < &hdr.digis[hdr.ndigis]; hp++){
/* Print digi string */
pax25(tmp,hp);
strcat(header,tmp);
strcat(header,(hp->ssid & REPEATED) ? "*":" ");
}
}
if(pullone(bpp,&control) != 1){
twprintf("%s\n",header);
return;
}
type = ftype(control);
strcat(header,decode_type(type));
/* Dump poll/final bit */
if(control & PF){
switch(hdr.cmdrsp){
case COMMAND:
strcat(header,"(P)");
break;
case RESPONSE:
strcat(header,"(F)");
break;
default:
strcat(header,"(P/F)");
break;
}
}
twputs(header);
/* Dump sequence numbers */
if((type & 0x3) != U) /* I or S frame? */
twprintf(" NR=%d",(control>>5)&7);
if(type == I || type == UI){
if(type == I)
twprintf(" NS=%d",(control>>1)&7);
/* Decode I field */
if(pullone(bpp,&pid) == 1){ /* Get pid */
if(pid == PID_SEGMENT){
unsegmented = 0;
pullone(bpp,&seg);
twprintf("%s remain %u", (seg & SEG_FIRST) ?
" First seg;" : "", seg & SEG_REM);
if(seg & SEG_FIRST)
pullone(bpp,&pid);
} else
unsegmented = 1;
temp = *bpp;
if (pid == PID_NO_L3 && temp->cnt >= 20
&& temp->data[0] == 0x45
&& temp->data[1] == 0x00
&& temp->data[2] < 0x02){
pid = PID_IP;
ipcam = 1;
}
else
ipcam = 0;
if(pid == PID_SEGMENT)
twprintf("\n");
else{
twprintf(" pid=");
switch(pid){
case PID_ARP:
twprintf("ARP\n");
arp_dump(bpp);
break;
case PID_NETROM:
twprintf("NET/ROM\n");
netrom_dump(bpp);
break;
case PID_IP:
twprintf("IP\n");
ip_dump(bpp,unsegmented);
break;
case PID_NO_L3:
twprintf("Text\n");
break;
default:
twprintf("0x%x\n",pid);
}
}
}
} else if(type == FRMR && pullup(bpp,tmp,3) == 3){
sprintf(buf," Vr = %d Vs = %d",(tmp[1] >> 5) & MMASK,
(tmp[1] >> 1) & MMASK);
if(tmp[2] & W)
strcat(buf," Invalid control field");
if(tmp[2] & X)
strcat(buf," Illegal I-field");
if(tmp[2] & Y)
strcat(buf," Too-long I-field");
if(tmp[2] & Z)
strcat(buf," Invalid seq number");
twprintf(":\n%s %s\n",decode_type(ftype(tmp[0])),buf);
}
else
twprintf("\n");
}
/* Display NET/ROM network and transport headers */
static void netrom_dump(struct mbuf **bpp)
{
struct ax25_addr src,dest;
char x;
char tmp[16];
char thdr[5];
register i;
if(bpp == NULLBUFP || *bpp == NULLBUF)
return;
/* See if it is a routing broadcast */
if(uchar(*(*bpp)->data) == 0xff) {
pullone(bpp,tmp); /* Signature */
pullup(bpp,tmp,ALEN);
tmp[ALEN] = '\0';
twprintf("NET/ROM Routing: %s\n",tmp);
for(i = 0;i < 11;i++) {
if (pullup(bpp,tmp,AXALEN) < AXALEN)
break;
memcpy(src.call,tmp,ALEN);
src.ssid = tmp[ALEN];
pax25(tmp,&src);
twprintf(" %12s",tmp);
pullup(bpp,tmp,ALEN);
tmp[ALEN] = '\0';
twprintf("%8s",tmp);
pullup(bpp,tmp,AXALEN);
memcpy(src.call,tmp, ALEN);
src.ssid = tmp[ALEN];
pax25(tmp,&src);
twprintf(" %12s", tmp);
pullone(bpp,tmp);
twprintf(" %3u\n", (unsigned)uchar(tmp[0]));
}
return;
}
/* Decode network layer */
pullup(bpp,tmp,AXALEN);
memcpy(src.call,tmp,ALEN);
src.ssid = tmp[ALEN];
pax25(tmp,&src);
twprintf("NET/ROM: %s",tmp);
pullup(bpp,tmp,AXALEN);
memcpy(dest.call,tmp,ALEN);
dest.ssid = tmp[ALEN];
pax25(tmp,&dest);
twprintf("->%s",tmp);
pullup(bpp,&x,1);
twprintf(" ttl %d\n",uchar(x));
/* Read first five bytes of "transport" header */
pullup(bpp,thdr,5);
switch((thdr[4] & 0xf) | (thdr[0] & IPVERSION << 4)){
case 0: /* network PID extension */
case (0 | IPVERSION << 4): /* try to handle old IP format */
case (1 | IPVERSION << 4): /* try to handle old IP format */
case (2 | IPVERSION << 4): /* try to handle old IP format */
case (3 | IPVERSION << 4): /* try to handle old IP format */
case (4 | IPVERSION << 4): /* try to handle old IP format */
case (5 | IPVERSION << 4): /* try to handle old IP format */
case (6 | IPVERSION << 4): /* try to handle old IP format */
if (thdr[0] == NRPROTO_IP && thdr[1] == NRPROTO_IP)
ip_dump(bpp,1) ; /* new format of IP over NET/ROM */
else
{
twprintf(" protocol family %x, proto %x",
uchar(thdr[0]), uchar(thdr[1])) ;
/* Try to use IPVERSION value to descriminate */
/* maybe it's an old format IP datagram! */
if ((thdr[0] & 0xf0) == IPVERSION << 4)
{
struct mbuf *thbuf, *save ;
twprintf(" - old format IP\n");
if ((thbuf = alloc_mbuf(5)) == NULLBUF) break ;
thbuf->cnt = 5 ;
memcpy(thbuf->data,thdr,5) ;
save = *bpp ;
*bpp = thbuf ;
append(bpp,save) ;
ip_dump(bpp,1) ;
}
}
break;
case 1: /* Connect request */
twprintf(" conn rqst: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
pullone(bpp,&x);
twprintf(" wnd %d",x);
pullup(bpp,(char *)&src,AXALEN);
pax25(tmp,&src);
twprintf(" %s",tmp);
pullup(bpp,(char *)&dest,AXALEN);
pax25(tmp,&dest);
twprintf("@%s",tmp);
break;
case 2: /* Connect acknowledgement */
twprintf(" conn ack: ur ckt %d/%d my ckt %d/%d",
uchar(thdr[0]), uchar(thdr[1]), uchar(thdr[2]),
uchar(thdr[3]));
pullone(bpp,&x);
twprintf(" wnd %d",x);
break;
case 3: /* Disconnect request */
twprintf(" disc: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
break;
case 4: /* Disconnect acknowledgement */
twprintf(" disc ack: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
break;
case 5: /* Information (data) */
twprintf(" info: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
twprintf(" txseq %d rxseq %d",uchar(thdr[2]), uchar(thdr[3]));
break;
case 6: /* Information acknowledgement */
twprintf(" info ack: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
twprintf(" txseq %d rxseq %d",uchar(thdr[2]), uchar(thdr[3]));
break;
default:
twprintf(" unknown transport type %d", thdr[4] & 0x0f) ;
/* Try to use IPVERSION value to descriminate */
/* maybe it's an old format IP datagram! */
if ((thdr[0] & 0xf0) == IPVERSION << 4)
{
struct mbuf *thbuf, *save ;
twprintf(" - old format IP\n");
if ((thbuf = alloc_mbuf(5)) == NULLBUF) break ;
thbuf->cnt = 5 ;
memcpy(thbuf->data,thdr,5) ;
save = *bpp ;
*bpp = thbuf ;
append(bpp,save) ;
ip_dump(bpp,1) ;
}
break;
}
if(thdr[4] & 0x80)
twprintf(" CHOKE");
if(thdr[4] & 0x40)
twprintf(" NAK");
twprintf("\n");
}
char *decode_type(int16 type)
{
switch(uchar(type)){
case I:
return "I";
case SABM:
return "SABM";
case DISC:
return "DISC";
case DM:
return "DM";
case UA:
return "UA";
case RR:
return "RR";
case RNR:
return "RNR";
case REJ:
return "REJ";
case FRMR:
return "FRMR";
case UI:
return "UI";
default:
return "[invalid]";
}
}